/**
 * Project Name:九色鹿
 * File Name:ExceptionsHandler.java
 * Package Name:com.fxp.project.jiuselu.web.handler
 * Date:2021-08-29 12:17 下午
 * Copyright (c) 2021, Jason.Wang All Rights Reserved.
 */
package com.fxp.project.jiuselu.web.handler;

import com.alibaba.fastjson.JSON;
import com.fxp.project.jiuselu.commons.code.RetCode;
import com.fxp.project.jiuselu.commons.constant.ConstantCode;
import com.fxp.project.jiuselu.commons.exceptions.JiuLuException;
import com.fxp.project.jiuselu.commons.exceptions.ParamException;
import com.fxp.project.jiuselu.web.domain.CommonResult;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.util.Optional;

/**
 * ClassName: ExceptionsHandler<br/>
 * Function: 统一错误控制器<br/>
 * Date: 2021-08-29 12:17 下午<br/>
 *
 * @author Jason.Wang
 * @version 1.0.0.0
 * @see
 * @since JDK 1.8
 */
@Log4j2
@ControllerAdvice
public class ExceptionsHandler {

    /**
     * customerExceptionHandler: 自定义的业务异常信息<br/>
     *
     * @param jiuLuException
     * @return
     * @author Jason.Wang
     * @createTime 2020/3/12 22:10
     */
    @ResponseBody
    @ExceptionHandler(value = JiuLuException.class)
    @ResponseStatus(value = HttpStatus.OK)
    public CommonResult<String> customerExceptionHandler(JiuLuException jiuLuException) {
        log.warn("catch business exception", jiuLuException);
        RetCode retCode = Optional.ofNullable(jiuLuException).map(JiuLuException::getRetCode).orElse(ConstantCode.SYSTEM_EXCEPTION);
        CommonResult<String> bre = new CommonResult<>(retCode.getCode(), retCode.getMessage(), null);
        log.warn("business exception return:{}", JSON.toJSONString(bre));
        return bre;
    }

    /**
     * paramExceptionHandler: 捕获参数异常信息<br/>
     *
     * @param paramException
     * @return
     * @author Jason.Wang
     * @createTime 2020/3/12 22:11
     */
    @ResponseBody
    @ExceptionHandler(value = ParamException.class)
    @ResponseStatus(value = HttpStatus.OK)
    public CommonResult<String> paramExceptionHandler(ParamException paramException) {
        log.warn("catch param exception", paramException);
        RetCode retCode = Optional.ofNullable(paramException).map(ParamException::getRetCode).orElse(ConstantCode.SYSTEM_EXCEPTION);
        CommonResult<String> bre = new CommonResult<>(retCode.getCode(), retCode.getMessage(), null);
        log.warn("param exception return:{}", JSON.toJSONString(bre));
        return bre;
    }

    /**
     * typeMismatchExceptionHandler: 类型不匹配异常<br/>
     *
     * @param ex
     * @return
     * @author Jason.Wang
     * @createTime 2020/3/12 22:11
     */
    @ResponseBody
    @ExceptionHandler(value = TypeMismatchException.class)
    @ResponseStatus(value = HttpStatus.OK)
    public CommonResult<String> typeMismatchExceptionHandler(TypeMismatchException ex) {
        log.warn("catch typeMismatchException", ex);

        RetCode retCode = new RetCode(ConstantCode.PARAM_EXCEPTION.getCode(), ex.getMessage());
        CommonResult<String> bre = new CommonResult<>(retCode.getCode(), retCode.getMessage(), null);
        log.warn("typeMismatchException return:{}", JSON.toJSONString(bre));
        return bre;
    }


    /**
     * accessDeniedExceptionHandler: 访问权限异常<br/>
     *
     * @param exception
     * @return
     * @throws Exception
     * @author Jason.Wang
     * @createTime 2020/3/12 22:12
     */
    @ResponseBody
    @ExceptionHandler(value = AccessDeniedException.class)
    @ResponseStatus(value = HttpStatus.OK)
    public CommonResult<String> accessDeniedExceptionHandler(AccessDeniedException exception) throws Exception {
        log.warn("catch accessDenied exception", exception);
        CommonResult<String> bre = new CommonResult<>(ConstantCode.ACCESS_DENIED.getCode(), ConstantCode.ACCESS_DENIED.getMessage(), null);
        log.warn("accessDenied exception return:{}", JSON.toJSONString(bre));
        return bre;
    }

    /**
     * exceptionHandler: 运行时异常<br/>
     *
     * @param exc
     * @return
     * @author Jason.Wang
     * @createTime 2020/3/12 22:12
     */
    @ResponseBody
    @ExceptionHandler(value = RuntimeException.class)
    @ResponseStatus(value = HttpStatus.OK)
    public CommonResult<String> exceptionHandler(RuntimeException exc) {
        log.warn("catch RuntimeException", exc);
        // 默认系统异常
        CommonResult<String> bre = new CommonResult<>(ConstantCode.PARAM_EXCEPTION.getCode(), ConstantCode.PARAM_EXCEPTION.getMessage(), null);
        log.warn("system RuntimeException return:{}", JSON.toJSONString(bre));
        return bre;
    }
}
